home *** CD-ROM | disk | FTP | other *** search
- NAME msxz10
- ; File MSXZ10.ASM
- include mssdef.h
- ; Copyright (C) 1982,1991, Trustees of Columbia University in the
- ; City of New York. Permission is granted to any individual or
- ; institution to use, copy, or redistribute this software as long as
- ; it is not sold for profit and this copyright notice is retained.
- ; Kermit system dependent module for Heath/Zenith Z100
- ; Edit history
- ; 2 March 1991 version 3.10
- ; Last change: 3 November 1990.
- ;
- ; OUTCH2 defined as far label.
- ; Replay code in PRTCHR modified per ibm pc version and call serrst added at
- ; label coms0. These two last changes are for version 3.02.
- ; New code for VTS and VTSTAT added and under revision but not active. These
- ; two routines and corresponding data really belong in msy but the routines
- ; and some of their data are kept here to make msy small enough to assemble
- ; with MASM 4. DUMPSCR moved to msyz10.asm.
- ; A number of calls to SPRTCH added in order to allow windowing for the non
- ; interupt driven S-100 modem ports COM3/COM4. Some very limited success at
- ; 1200 baud would indicate that it might work at 300 (untested).
- ; SERISR optimized and performance improved for COM1/COM2. However, there are
- ; still some problems from 19200 baud and up, in particular with windowing.
- ; OUTCHR significantly rewritten. Modified CHKXON (COM1/2) and CHKXOF (COM3/4)
- ; to call OUTCH5 and OUTCH2 respectively rather than OUTCHAR.
- ; SERISR significantly modified to improve flow control for COM1/2 and SPRTCH
- ; fixed to ignore flow control for COM3/4 if not called for.
- ; Minor correction to WAIT01. CLEARL and CTLU merged.
- ; PUTHLP display routine improved and replay command implemented.
- ; Increased size of buffilen and buffolen. Added register save to BEEP.
- ; Added routines ENA_WRP and DIS_WRP and several calls to these to make serial
- ; display behave. Help message for 'set port' improved.
- ; Various cosmetic changes.
- ;
- ; First version of this file for MS-Kermit 3.0: 8 May 1990.
- ; Bo Gedda
- ;
- ; Support for 2 US Robotics S-100 modems at ports 20H (com3) and 2EH (com4).
- ; com1 (1 in status list) means serial port B.
- ; com2 (2 in status list) means serial port A.
- ; com3 (3 in status list) means S-100 port 1 (20H).
- ; com4 (4 in status list) means S-100 port 2 (2EH).
- ;
- public getbaud, serini, serrst, clrbuf, outchr, coms, vts, vtstat
- public ctlu, cmblnk, locate, prtchr, baudst, clearl, bdtab, dodel
- public beep, sprtch, klen, ktab, krpl, getivec, setivec, dupflg
- public count, xofsnt, puthlp, putmod, clrmod, poscur, pcwait
- public sendbr, sendbl, machnam, lclini, outch2, dis_scan
- public ihosts, ihostr, dtrlow, mdmhand, shomodem, getmodem
- public portval, port1, port2, port3, port4, serhng, ena_scan
- public flowon, flowoff, sescur, sesdisp, setnbios, peekcom, parmsk
-
- off equ 0
- false equ 0
- true equ 1
- bufon equ 1 ; buffer level xon/xoff on-state control flag
- usron equ 2 ; user level xon/xoff on-state control flag
- mntrgh equ bufsiz*3/4 ; High point = 3/4 of buffer full
- mntrgl equ bufsiz/4 ; Low point = 1/4 buffer full
- xoftime equ 15 ; 15 seconds time out for xoff, see timer
-
- ; constants used by serial port handler
-
- ; Z-100 standard serial ports A (J1) and B (J2), called COM2 and COM1 here.
- ; Note that A=J1=COM2=2 and B=J2=COM1=1. Port B is the standard modem port
- ; similar to an IBM PC port. Thats why.
- ; serial port information
- TSRE EQU 004H
- THBE EQU 001H
- DTR EQU 002H
- DTROFF EQU 0fdH
- RTS EQU 020H
- RTSOFF EQU 0dfH
- DCD EQU 040H
- DSR EQU 080H
- RDA EQU 002H
- J1_ADDR EQU 0e8H
- J2_ADDR EQU 0ecH
- PDATA EQU 0
- PSTATUS EQU 1
- PMODE EQU 2
- PCOMM EQU 3
- TXON EQU 001H
- TXOFF EQU 0feH
- RXON EQU 004H
- RXOFF EQU 0fbH
- MODE1 EQU 04dH
- MODE2 EQU 030H ; must be ORed with appropriate baud rate
- Z8259 EQU 0f2H
- EOI EQU 020H
- J1INT EQU 68
- J2INT EQU 69
- BUFILEN EQU bufsiz
- BUFOLEN EQU bufsiz/2
-
- BRKBIT EQU 048H ; Send-break bit.
-
- mdmdat1 equ J2_ADDR ; Address of serial port B (J2)
- mdmcom1 equ J2_ADDR + PCOMM ; Address of serial port B command
- mdmdat2 equ J1_ADDR ; Address of serial port A (J1)
- mdmcom2 equ J1_ADDR + PCOMM ; Address of serial port A command
-
- ;US Robotics S-100 modem using 8251A USART data
- mdmdat3 equ 020h ; Address of USR S-100 port 1
- mdmcom3 equ mdmdat3 + 1 ; Address of USR S-100 command port
- mdmdat4 equ 02eh ; Address of USR S-100 port 2
- mdmcom4 equ mdmdat4 + 1 ; Address of USR S-100 command port
- modsndb equ 1h ; Bit to test for send S-100 modem
- modrcvb equ 2h ; Bit to test for receive S-100 modem
- modperb equ 8h ; Parity error detect bit S-100 modem
- modorub equ 10h ; Overrun error detect bit
- moddcdb equ 80h ; Carrier detect bit S-100 modem
-
- COLUMNS EQU 80 ; Characters per screen line.
- ROWS EQU 24 ; Text lines per screen
- VID_CMD EQU 0d8h ; Video-memory control port.
- PAR_GRN EQU 0e000h ; Green video plane segment address.
-
- ; external variables used:
- ; flags - global flags as per flginfo structure defined in pcdefs
- ; trans - global transmission parameters, trinfo struct defined in pcdefs
- ; portval - pointer to current portinfo structure (currently either port1,
- ; port2, port3 or port4 )
- ; port1, port2, port3, port4 - portinfo structures for the corresponding ports
- ; monmode - color/monochrome mode of monitor
- ; dmpname - file name for screen dump file
-
- ; global variables defined in this module:
- ; xofsnt, xofrcv - tell whether we saw or sent an xoff.
-
- BIOS_SEG SEGMENT AT 40H ; Define segment where BIOS really is
- ORG 1*3
- BIOS_STATUS LABEL FAR ; Console input status
- ORG 2*3
- BIOS_CONIN LABEL FAR ; Console input
- ORG 3*3
- BIOS_CONOUT LABEL FAR ; Console output
- ORG 4*3
- BIOS_PRINT LABEL FAR ; Printer output
- ORG 6*3
- BIOS_AUXOUT LABEL FAR ; AUX output routine
- ORG 25*3
- BIOS_PRNFUNC LABEL FAR ; PRN: FUNCTION
- ORG 26*3
- BIOS_AUXFUNC LABEL FAR ; AUX: function
- ORG 27*3
- BIOS_CONFUNC LABEL FAR ; CON: function
- BIOS_SEG ENDS
-
- ; Define functions of BIOS_CONFUNC, BIOS_PRNFUNC, and BIOS_AUXFUNC
- CHR_WRITE EQU 0 ; Write function
- CHR_READ EQU CHR_WRITE+1 ; Read function
- CHR_STATUS EQU CHR_READ+1 ; Status function
- CHR_SFGS EQU 0 ; Get status subfunction
- CHRS_WA EQU 00000001B ; <ETX> sent, waiting for <ACK>
- CHRS_WD EQU 00000010B ; <DC3> seen, waiting for <DC1>
- CHRS_SN EQU 00000100B ; Sending nulls
- CHRS_TXR EQU 10000000B ; Transmitter ready to send data
- CHRS_RXR EQU 01000000B ; Receiver has data
- CHRS_RXOF EQU 00100000B ; Receiver queue overflow
- CHRS_RXE EQU 00010000B ; Other type of reciver error
- CHRS_TXE EQU 00001000B ; Transmitter error
- CHR_SFGC EQU CHR_SFGS+1 ; Get configuration info subfunction
- CHR_CONTROL EQU CHR_STATUS+1 ; Control function
- CHR_CFSU EQU 0 ; Setup new configuration parms subfunction
- CHR_CFCI EQU CHR_CFSU+1 ; Clear input subfunction
- CHR_CFCO EQU CHR_CFCI+1 ; Clear output subfunction
- CHR_LOOK EQU CHR_CONTROL+1; Nondestructive read function
- CHR_FMAX EQU CHR_LOOK ; Maximum function number
-
- ; storage for port configuration
- cfginfo struc
- cfclass db 0
- cfattr db 0
- cfport dw 0
- cfbaud db 0
- cfhshk db 0
- cfbctl db 0
- cfecnt db 0
- cfncnt db 0
- cfnchr db 0
- cfres db 6 dup(?)
- cfsize db 0
- cfginfo ends
-
- ; structure for status information table sttab.
- stent struc
- sttyp dw ? ; type (actually routine to call)
- msg dw ? ; message to print
- val2 dw ? ; needed value: another message, or tbl addr
- tstcel dw ? ; address of cell to test, in data segment
- basval dw 0 ; base value, if non-zero
- stent ends
-
- data segment
- extrn flags:byte, trans:byte, taklev:byte, verident:byte
- extrn comptab:byte, termtb:byte, ontab:byte, scrtab:byte
- extrn cntltab:byte, beltab:byte, curtab:byte, chatab:byte
- extrn kpamtab:byte, dirtab:byte, doscol:byte
- extrn lclsusp:word, lclrest:word, lclexit:word, dosflg:byte
- extrn dosflg1:byte, repflg:byte, diskio:byte, kstatus:byte
- extrn holdscr:byte, vtemu:word, lincur:word
- extrn belltype:byte, vtroll:byte
-
- oldoff dw 0
- oldseg dw 0
- sescur dw 0
- dupflg db 0 ; full (0) or half (1) duplex on port
- brkval db 0 ; What to send for a break.
- brkdur dw 0 ; Length of break in centiseconds
- badbd db cr,lf,'Unimplemented baud rate$'
- noimp db cr,lf,'Not implemented$'
- coms0msg db cr,lf,'No US Robotics S-100 modem detected at this port!'
- db cr,lf,'$'
- comsmsg db ' One of the following:'
- db cr,lf,' 1 2 3 4 COM1 COM2 COM3 COM4 A B J1 J2'
- db cr,lf,lf,'Where'
- db cr,lf,' 1 = COM1 = Serial Port B = J2'
- db cr,lf,' 2 = COM2 = Serial Port A = J1'
- db cr,lf,' 3 = COM3 = US Robotics S-100 modem at port 20H'
- db cr,lf,' 4 = COM4 = US Robotics S-100 modem at port 2EH$'
- vtsmsg db cr,lf,'The Z-100 terminal has inherent HEATH-19 support.'
- db cr,lf,' Set terminal none activates native Heath-19 '
- db 'properties.',cr,lf
- db ' This deactivates key mapping and scan codes.$'
- msmsg0 db cr,lf,' Modem may be ready: DSR is unknown$'
- msmsg1 db cr,lf,' Modem is not ready: DSR is off$'
- msmsg2 db cr,lf,' Modem is ready: DSR is on$'
- msmsg3 db cr,lf,' no Carrier Detect: CD is off$'
- msmsg4 db cr,lf,' Carrier Detect: CD is on$'
- msmsg5 db cr,lf,' no Clear To Send: CTS is off$'
- msmsg6 db cr,lf,' Clear To Send: CTS is on$'
- msmsg7 db cr,lf,' Modem is not used by the Network$'
- not_z db 'Sorry, wrong software!',cr,lf
- db 'This Kermit will only run on the Z-100 -- a non '
- db 'IBM PC compatible',cr,lf,lf
- machnam db 'Heath-Zenith_Z-100$'
- com3ms db 'Carrier detected at S-100 Port 20H, COM3',cr,lf,'$'
- com4ms db 'Carrier detected at S-100 Port 2EH, COM4',cr,lf,'$'
- com3ms1 db 'Modem detected at S-100 Port 20H, COM3',cr,lf,'$'
- com4ms1 db 'Modem detected at S-100 Port 2EH, COM4'
- crlf db cr,lf,'$'
- infmsg db 'S-100 MODEM INITIALIZATION FAILURE',cr,lf,'$'
- wmsg db cr,lf,' CARRIER detected -- disconnecting',cr,lf,'$'
- dscmsg db cr,lf,' DISCONNECTED',cr,lf,'$'
- ndscmsg db cr,lf,' !!! WARNING >>> NOT DISCONNECTED !!!',cr,lf,'$'
- hngstr db '+++$'
- hngmsg db cr,lf,' The phone should have hungup.',cr,lf,'$' ; [jrd]
- hnghlp db cr,lf,' The modem control lines DTR and RTS for the current'
- db ' port are forced low (off)'
- db cr,lf,' to hangup the phone. Normally, Kermit leaves them'
- db ' high (on) when it exits.'
- db cr,lf,lf,' The USR S-100 modem is hung up using "+++".'
- db cr,lf,'$'
- rdbuf db 80 dup (?) ; temp buf [jrd]
- delstr db BS,BS,' ',BS,BS,'$' ; Delete string
- clrlin db BS,BS,' ',cr,'$' ; Clear line (just the cr part)
- home db ESCAPE,'H$' ; Home cursor
- clrstr db ESCAPE,'E$' ; Home cursor and erase entire display
- eeolstr db ESCAPE,'K$' ; Erase to end of line
- enamod db ESCAPE,'x1$' ; Enable 25th line
- dismod db ESCAPE,'y1$' ; Disable 25th line
- enascan db ESCAPE,'y?$' ; Enable scan codes, disable key expansion
- disscan db ESCAPE,'x?$' ; Disable scan codes, enable key expansion
- begrev db ESCAPE,'p$' ; Enter reverse video
- endrev db ESCAPE,'q$' ; Exit reverse video
- lin25 db ESCAPE,'Y8 $' ; Column 1 row 25
- savcur db ESCAPE,'j$' ; Save current cursor position
- precur db ESCAPE,'k$' ; Restore cursor to previous position
- monstr db ESCAPE,'i0$' ; Return montior information
- portin db -1 ; Has comm port been initialized?
- ; -1=has not used, 1=is used, 0=has been used
- xofsnt db 0 ; Say if we sent an XOFF
- xofrcv db 0 ; Say if we received an XOFF
- parmsk db 0ffh ; parity mask, 0ffh for no parity, 07fh with
- flowoff db 0 ; flow-off char, Xoff or null (if no flow)
- flowon db 0 ; flow-on char, Xon or null
- tmp db 0,'$'
- temp dw 0 ; Temporary storage.
- mddat0 dw 0 ; Storage for modem data port
- mdstat0 dw 0 ; Storage for modem status port
- savedi dw offset source ; Temporary storage for di
- srcpnt dw offset source ; where to read next serial port byte
- source db bufsiz dup(0) ; S-100 port input buffer
- timer db 0
- timer0 db 0
- ; begin Terminal emulator data set
- portmax equ 4 ; number of predefined ports
-
- port1 prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0>
- port2 prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0>
- port3 prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0>
- port4 prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0>
- rept portmax-4
- prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0>
- endm
- portval dw port1 ; Default is to use port 1
-
- bdtab db 16 ; 16 entries
- mkeyw '45.5',0
- mkeyw '50 ',1
- mkeyw '75 ',2
- mkeyw '110 ',3
- mkeyw '134.5',4
- mkeyw '150',5
- mkeyw '300',6
- mkeyw '600',7
- mkeyw '1200',8
- mkeyw '1800',9
- mkeyw '2000',10
- mkeyw '2400',11
- mkeyw '4800',12
- mkeyw '9600',13
- mkeyw '19200',14
- mkeyw '38400',15
-
- bdtab12 db 16 ; 16 (yes 16) entries for com1 and com2
- mkeyw '45.5',0
- mkeyw '50 ',1
- mkeyw '75 ',2
- mkeyw '110 ',3
- lbdtab12 equ $-bdtab12 ; length of table
-
-
- bdtab34 db 4 ; 4 entries for com3 and com4, s-100 modem
- mkeyw '150 ',0
- mkeyw '300',1
- mkeyw '600',2
- mkeyw '1200',3
-
- ; this table is indexed by the baud rate definitions given in
- ; bdtab. Unsupported baud rates should contain 0FFH.
- bddat label word
- dw 0 ; 45.5 baud
- dw 1 ; 50 baud
- dw 2 ; 75 baud
- dw 3 ; 110 baud
- dw 4 ; 134.5 baud
- dw 5 ; 150 baud
- dw 6 ; 300 baud
- dw 7 ; 600 baud
- dw 8 ; 1200 baud
- dw 9 ; 1800 baud
- dw 10 ; 2000 baud
- dw 11 ; 2400 baud
- dw 12 ; 4800 baud
- dw 13 ; 9600 baud
- dw 14 ; 19200 baud
- dw 15 ; 38400 baud
- lbddat equ $-bddat ; length of table
-
- bddat12 label word ; for com1 and com2
- dw 0 ; 45.5 baud
- dw 1 ; 50 baud
- dw 2 ; 75 baud
- dw 3 ; 110 baud
- dw 4 ; 134.5 baud
- dw 5 ; 150 baud
- dw 6 ; 300 baud
- dw 7 ; 600 baud
- dw 8 ; 1200 baud
- dw 9 ; 1800 baud
- dw 10 ; 2000 baud
- dw 11 ; 2400 baud
- dw 12 ; 4800 baud
- dw 13 ; 9600 baud
- dw 14 ; 19200 baud
- dw 15 ; 38400 baud
-
- bddat34 label word ; for com3 and com4, s-100 modem
- dw 0 ; 150 baud
- dw 1 ; 300 baud
- dw 2 ; 600 baud
- dw 3 ; 1200 baud
- dw 0ffh
- dw 0ffh
- dw 0ffh
- dw 0ffh
- dw 0ffh
- dw 0ffh
- dw 0ffh
- dw 0ffh
- dw 0ffh
- dw 0ffh
- dw 0ffh
- dw 0ffh
-
- ; baud rate data for S-100 modem
- bd150 db 4fh ; Low speed mode byte (150/300)
- db 17h ; Low speed command byte (150/600)
- bd300 db 4fh ; Low speed mode byte (150/300)
- db 37h ; High speed command byte(300/1200)
- bd600 db 4eh ; High speed mode byte (600/1200)
- db 17h ; Low speed command byte (150/600)
- bd1200 db 4eh ; High speed mode byte (300/1200)
- db 37h ; High speed command byte(300/1200)
-
- ; S-100 COM3/COM4 default baud rate: 0=150, 1=300, 2=600, 3=1200 baud
- bds100 equ 3 ; Set to 0, 1, 2, or 3
-
- ; S-100 modem set up string
- ; echo commands, use extended result codes, do not answer call
- set_str db 'ATE1X1S0=0',cr,'$'
-
- auxconf cfginfo <>
-
- ; variables for serial interrupt handler
-
- count dw 0 ; Number of chars in int buffer.
- buffin db BUFILEN+2 dup(?) ; input buffer
- bufibeg dw 0
- bufiend dw 0
- buffout db BUFOLEN+2 dup(?) ; output buffer
- bufobeg dw 0
- bufoend dw 0
- portadr dw 0
- intin db 0 ; port int installed flag
- mdmhand db 0 ; Modem status
-
-
- ourarg termarg <>
-
- klen dw ? ; length of key redefinition table
- ktab dw ? ; address of key redefinition table
- krpl dw ? ; address of key replacement table
-
- colortb db 0,4,2,6,1,5,3,7 ; color reversed-bit setting bytes
- clrset db ? ; Temp for SET Term Tabstops xxx
-
- ; This is data for the extended set terminal parameters. It was put here
- ; in order to keep the size of msyz10.asm within limits for assembly by
- ; MASM 4. The corresponding code is conatained in VTS and VTSTAT below.
- erms41 db cr,lf,'?More parameters are needed$'
- vthlp db ' one of the following:',cr,lf
- db ' terminal types of: None, Heath-19, VT52, VT102, VT320,'
- db ' or Tek4010',cr,lf
- db ' Newline-mode Cursor-style Character-set'
- db cr,lf
- db ' Keyclick Margin-bell Screen-background'
- db ' (normal, reverse)',cr,lf
- db ' Tabstops Wrap (long lines) Color (fore & background)'
- db cr,lf,' Bell audible or visual'
- db cr,lf,' Clear-screen (clears old startup screen)'
- db cr,lf,' Controls 7-bit or 8-bit (permits VT320 to use'
- db ' 8-bit control sequences (C1))'
- db cr,lf,' Direction Left-to-right or Right-to-left'
- db ' (screen writing direction)'
- db cr,lf,' Graphics (type of display adapter when in Tek4010'
- db ' mode)'
- db cr,lf,' Keypad numeric (normal) or application mode'
- db cr,lf,' Replay filespec (display a file through the emulator)'
- db cr,lf,' Rollback (undo screen roll back before writing new'
- db ' chars, default=off)$'
- clrhlp db ' one of the following:'
- db cr,lf,' AT #s (to set tabs at column #s) or'
- db ' AT start-column:spacing'
- db cr,lf,' Clear AT #s (clears individual tabs) or'
- db ' AT start-column:spacing'
- db cr,lf,' Clear ALL (to clear all tabstops)'
- db cr,lf,' Ex: Set term tab at 10, 20, 34 sets tabs'
- db cr,lf,' Ex: Set term tab at 1:8 sets tabs at 1, 9,'
- db cr,lf,' Ex: Set term tab clear at 9, 17, 65 clears tabs'
- db cr,lf,' Ex: Set term tab clear at 1:8 clears tabs at 1, 9,'
- db ' 17,...$'
- tbserr db cr,lf,'?Column number is not in range 1 to screen width-1$'
- colhlp db cr,lf,' Set Term Color value, value, value, ...'
- db cr,lf,' 0 no-snow mode on an IBM CGA and white on black'
- db cr,lf,' 1 for high intensity foreground'
- db cr,lf,' 10 for fast CGA screen updating (may cause snow)'
- db cr,lf,' Foreground color (30-37) = 30 + sum of colors'
- db cr,lf,' Background color (40-47) = 40 + sum of colors'
- db cr,lf,' where colors are 1 = red, 2 = green, 4 = blue'
- db cr,lf,' Ex: 0, 1, 37, 44 IBM CGA(0), bright(1) white(37)'
- db ' chars on a blue(44) field'
- db cr,lf,' Attributes are applied in order of appearance.$'
- colerr db cr,lf,'?Value not in range of 0, 1, 10, 30-37, or 40-47$'
- vtwrap db 'Term wrap-lines: $'
- vtbellm db 'Term margin-bell: $'
- vtnewln db 'Term newline: $'
- vtcur db 'Term cursor-style: $'
- vtcset db 'Term character-set: $'
- vtclik db 'Term key-click: $'
- vtscrn db 'Term screen-background: $'
- colst1 db 'Term color foregnd:3$'
- colst2 db ' backgnd:4$'
- vtrolst db 'Term rollback: $'
- vtdir db 'Term direction: $'
- vtcntst db 'Term controls: $'
- vtkpst db 'Term keypad: $'
- vtbset db 'Term bell: $'
- vtgchst db 'Term graph char: $'
- ; terminal emulator
- vtstbl stent <srchkw,vtcset,chatab,vtemu.vtchset> ; char set
- stent <srchkb,vtclik,ontab,vskeyclick,vtemu.vtflgop> ; keyclick
- stent <srchkb,vtwrap,ontab,vswrap,vtemu.vtflgop> ; line wrap
- stent <srchkb,vtcntst,cntltab,vscntl,vtemu.vtflgop> ; controls
- stent <srchkb,vtbellm,ontab,vsmarginbell,vtemu.vtflgop>;margin bell
- stent <srchkb,vtcur,curtab,vscursor,vtemu.vtflgop> ; cursor type
- stent <srchkw,vtbset,beltab,belltype> ; bell
- stent <srchkb,vtdir,dirtab,vswdir,vtemu.vtflgop> ; write direct
- stent <srchkb,vtnewln,ontab,vsnewline,vtemu.vtflgop> ; newline
- stent <srchkw,vtrolst,ontab,vtroll> ; rollback
- stent <srchkb,vtkpst,kpamtab,deckpam,vtemu.vtflgop> ; keypad
- stent <srchkb,vtscrn,scrtab,vsscreen,vtemu.vtflgop> ; screen
- dw 0 ; end of table
- ; end of Terminal data set
-
- vttbl db 19 ; number of entries
- mkeyw 'Bell',8800h ; note 8800 flag for decoding
- mkeyw 'Character-set',chaval+8300h
- mkeyw 'Clear-screen',8500h ; 8500h = marker here
- mkeyw 'Color',8200H ; screen fore/back colors; 200H=marker
- mkeyw 'Controls',cntlval
- mkeyw 'Cursor-style',curval
- mkeyw 'Direction',dirval
- mkeyw 'Graphics',8600h ; Tek graphics board, 800h=marker
- mkeyw 'Heath-19',ttheath+8100H; note 8100H flag for decoding here
- mkeyw 'Keyclick',keyval
- mkeyw 'Keypad',kpamval
- mkeyw 'Margin-bell',marval
- mkeyw 'None',ttgenrc+8100H
- mkeyw 'Newline',newval
- mkeyw 'Replay',8700h ; note 8700H flag for file replaying
- mkeyw 'Rollback',8400h ; note 8400H flag for decoding
- mkeyw 'Screen-background',scrval
- mkeyw 'Tabstops',tabval
- mkeyw 'Wrap',wraval
-
- vtsflg equ this word ; define small digits xxxval
- newval equ $-vtsflg ; 0 and mask for bit in byte
- dw vsnewline ; 1
- wraval equ $-vtsflg ; 2
- dw vswrap ; 2
- chaval equ $-vtsflg ; 4
- dw vsnrcm ; 4
- dirval equ $-vtsflg ; 6
- dw vswdir ; 8
- keyval equ $-vtsflg ; 8
- dw vskeyclick ; 10h
- marval equ $-vtsflg ; 10
- dw vsmarginbell ; 20h
- curval equ $-vtsflg ; 12
- dw vscursor ; 40h
- scrval equ $-vtsflg ; 14
- dw vsscreen ; 80h
- cntlval equ $-vtsflg ; 16
- dw vscntl ; 100h
- kpamval equ $-vtsflg ; 18
- dw deckpam ; 400h
- numflgs equ ($-vtsflg)/2 ; 10
- tabval equ $-vtsflg ; 20
- dw 0
- ;vtrtns dw numflgs dup (flgset), tabmod ; dispatch table for vtsflg
-
- data ends
-
- code segment public
- extrn comnd:near, dopar:near, defkey:near, getpos:near, atsclr:near
- extrn lclyini:near, setcol:near, srchkb:near, srchkw:near
- extrn csrtype:near
- assume cs:code, ds:data, es:nothing
-
- ; local initialization
- LCLINI proc near
- jmp lclini1 ; Bypass the exit code
- not_z10:mov ah,prstr
- mov dx,offset not_z ; This is not a Z-100, IBM PC maybe?
- int dos ; This program is for
- mov dx,offset verident ; display version header
- int dos
- mov ah,4ch ; terminate process
- int dos
- ; Find out if this is a Z-100
- ; We are doing that by looking for 0E9H at locations 0040:0000H
- ; and 0040:0003H which are in the Z-100 bios jump table.
- lclini1:mov bx,BIOS_SEG ; The segment at 40h
- mov ax,es ; Save es
- mov es,bx ; Set up the extra segment
- cmp byte ptr es:0,0e9h ; Z-100?
- jnz not_z10 ; No, it's probably IBM compatible
- cmp byte ptr es:3,0e9h ;Z-100?
- jnz not_z10 ; No, it's probably IBM compatible
- mov es,ax ; Restore es
- ;
- mov flags.vtflg,ttheath ; Set Heath-19 emulation mode, allows macs
- mov brkval,BRKBIT ; What to send for a break
- in al,mdmcom4 ; Check this port
- and al,modperb ; Is it there?
- jnz lclini3 ; No, skip
- mov dx,offset com4ms1
- mov ah,prstr ; Tell user it is there
- int dos
- in al,mdmcom4 ; Check again
- and al,moddcdb ; Carrier?
- jz lclini3 ; No, skip
- mov flags.comflg,4 ; Indicate s-100 port 2 for now
- mov portval,offset port4
- mov mddat0,mdmdat4
- mov mdstat0,mdmcom4
- mov ah,prstr ; Tell user
- mov dx,offset com4ms
- int dos
- lclini3:in al,mdmcom3 ; Check this port
- and al,modperb ; Is it there?
- jnz lclini4 ; No, skip
- mov dx,offset com3ms1
- mov ah,prstr ; Tell user it is there
- int dos
- in al,mdmcom3 ; Check again
- and al,moddcdb ; Carrier?
- jz lclini4 ; No, skip
- mov flags.comflg,3 ; Indicate s-100 port 1
- mov portval,offset port3
- mov mddat0,mdmdat3
- mov mdstat0,mdmcom3
- mov ah,prstr ; Tell user
- mov dx,offset com3ms
- int dos
- lclini4:
- call getbaud ; Which port of COM1/COM2 is default?
- ; Get baud rate from UARTs for this
- call baudref ; Set up baud rate references bdtab, bddat
- mov port3.baud,bds100 ; and put in default baud rate
- mov port4.baud,bds100 ; and put in default baud rate
- mov lclsusp,offset suspend ; call this when suspending to DOS
- mov lclrest,offset restore ; call this when returning from DOS
- mov lclexit,offset finexit ; call this when exiting Kermit
- call ena_wrp ; Make terminal wrap to next line at line end
- call lclyini ; let other modules initialize too...
- ret ; We are all done with lclini
- ;
- baudref:push di ; Rearrange bdtab and bddat
- push si
- push es
- mov ax,ds ; Set up
- mov es,ax ; pointers
- mov di,offset bddat ; to move baud
- mov si,offset bddat12 ; rate selection
- mov cx,lbddat ; length of table
- cmp flags.comflg,2 ; Ports 1/2
- jle lclini5 ; or ports 3/4?
- mov si,offset bddat34 ;Port 4!
- lclini5:cld
- rep movsb ; Move array
- mov di,offset bdtab ; This too
- mov si,offset bdtab12
- mov cx,lbdtab12 ; Length of table
- cmp flags.comflg,2 ; Ports 1/2
- jle lclini6 ; or ports 3/4?
- mov si,offset bdtab34 ;Port 4!
- lclini6:rep movsb ; Move array
- pop es ; Restore registers
- pop si
- pop di
- ret ; We're done
- LCLINI endp
-
- ; Call these routines when suspending Kermit to go to DOS
- suspend proc near
- call ihosts ; suspend the host
- call serrst
- call dis_scan ; disable scan code generation
- call dis_wrp ; disable sreen line wrap around
- ret
- suspend endp
-
- ; Call these routines when returning to Kermit from DOS
- restore proc near
- call serini ; reinit serial port
- call ihostr ; resume the host
- call ena_wrp ; enable screen line wrap around
- ret
- restore endp
-
- ; Call these routines when doing final exit of Kermit
- finexit proc near
- call serrst ; reset serial port
- call dis_scan ; disable scan code generation
- call dis_wrp ; disable sreen line wrap around
- ret
- finexit endp
-
- ; This routine, ena_scan, enables Z-100 scan code generation. It also
- ; disables extended key code generation. Modifies ax.
- ENA_SCAN PROC NEAR
- push dx
- mov ah,prstr
- mov dx,offset enascan
- int dos
- or dosflg1,1 ; say scan codes enabled
- pop dx
- ret
- ENA_SCAN ENDP
-
- ; This routine, dis_scan, disables Z-100 scan code generation. It also
- ; enables extended key code generatin. Modifies ax.
- DIS_SCAN PROC NEAR
- push dx
- mov ah,prstr
- mov dx,offset disscan
- int dos
- and dosflg1,0feh ; say scan codes disabled
- pop dx
- ret
- DIS_SCAN ENDP
-
- ; This routine, ena_wrp, enables wrap around at end of line.
- ; Modifies ax.
- ENA_WRP PROC NEAR
- push dx
- mov ah,conout
- mov dl,ESCAPE
- int dos
- mov dl,'v'
- int dos
- pop dx
- ret
- ENA_WRP ENDP
-
- ; This routine, dis_wrp, disables wrap around at end of line.
- ; Modifies ax.
- DIS_WRP PROC NEAR
- push dx
- mov ah,conout
- mov dl,ESCAPE
- int dos
- mov dl,'w'
- int dos
- pop dx
- ret
- DIS_WRP ENDP
-
- ; SHOW MODEM, displays current status of lines DSR, CD, and CTS.
- ; Uses byte mdmhand, the modem line status register. [jrd]
- shomodem proc near
- mov ah,cmeol ; get a confirm
- call comnd
- jc shomd5 ; c = failure
- mov dx,offset msmsg7 ; no modem status for network
- call getmodem ; get modem status
- mov ah,prstr
- cmp flags.comflg,2 ; port 1 or 2
- jle shomd0 ; yes, jump
- mov dx,offset msmsg0 ; not supported function
- jmp shomd1
- shomd0: mov dx,offset msmsg1 ; modem not ready msg
- test mdmhand,20h ; is DSR asserted?
- jz shomd1 ; z = not ready
- mov dx,offset msmsg2 ; modem ready msg
- shomd1: int dos
- mov dx,offset msmsg3 ; CD not asserted msg
- test mdmhand,80h ; CD asserted?
- jz shomd2 ; z = not asserted
- mov dx,offset msmsg4 ; CD asserted msg
- shomd2: int dos
- clc
- shomd5: ret
- shomodem endp
-
- ; Get modem status and set global byte mdmhand. Preserve all registers but dx.
- ; Returns with byte mdmhand in al, ah=0.
- getmodem proc near ; gets modem status upon request
- cmp flags.comflg,2 ; COM1 or COM2?
- jna getmodem2 ; na = yes, jump to handle these
- mov dx,mdstat0 ; Port address
- in al,dx ; Get status
- and al,moddcdb ; Carrier?
- mov mdmhand,0 ; Everything off
- jz getmodem1 ; z = yes, no carrier, done
- mov mdmhand,80h ; No, carrier detected
- getmodem1:jmp getmodem4 ; Done with COM3/COM4
- getmodem2:mov dx,portadr
- add dx,PSTATUS
- in al,dx
- mov mdmhand,0 ; Everything off
- test al,DSR ; DSR indicated?
- jz getmodem3 ; z = no, go on
- mov mdmhand,20h ; Indicate DSR
- getmodem3:test al,DCD ; CD indicated?
- jz getmodem4 ; z = no, go on
- or mdmhand,80h ; Indicate CD, don't touch DSR
- getmodem4:mov al,mdmhand ; Promised it here
- xor ah,ah ; A promise too
- clc ; Success
- ret
- getmodem endp
-
- ; Clear the input buffer. This throws away all the characters in the
- ; serial interrupt buffer. This is particularly important when
- ; talking to servers, since NAKs can accumulate in the buffer.
- CLRBUF PROC NEAR
- cmp flags.comflg,2 ; Ports 1/2?
- jg clrbuf1 ; g = no, do S-100 stuff
- cli
- push bx
- xor bx,bx
- mov bufoend,bx
- mov bufobeg,bx
- mov bufiend,bx
- mov bufibeg,bx
- pop bx
- mov count,0
- sti
- ret
- clrbuf1:push ax ; First empty port
- push dx
- mov dx,mddat0 ; Get possible
- in al,dx ; character
- pop dx
- pop ax ; then do it
- mov count,0 ; Nothing in buffer
- mov srcpnt,offset source ; Reset buffer
- mov savedi,offset source ; pointers
- ret
- CLRBUF ENDP
-
- ; Put the char in AH to the serial port, assumimg the port is active.
- ; Returns carry clear if success, else carry set.
- ; 16 May 1987 Add entry point OUTCH2 for non-flow controlled sending to
- ; prevent confusion of flow control logic at top of outchr; used by receiver
- ; buffer high/low water mark flow control code. [jrd]
- ; 14 September 1990 add entry point OUTCH5 for priority sending of xon;
- ; used by CHKXON and SERISR.
- OUTCHR PROC NEAR
- cmp flowoff,0 ; Are we doing flow control
- je outch2 ; No, just continue
- cmp ah,flowoff ; sending xoff?
- jne outch1 ; ne = no
- mov xofsnt,usron ; indicate user level xoff being sent
- jmp outch12
- outch1:and xofsnt,not usron ; cancel user level xoff
- cmp ah,flowon ; user sending xon?
- jne outch12 ; ne = no
- mov xofsnt,off ; say an xon has been sent (cancels xoff)
- outch12:mov timer,xoftime+1 ; Set delay to xoftime minimum, maximum+1 sec
- outch14:cmp xofrcv,true ; Are we being held (xoff received)?
- jnz outch2 ; no - it's OK to go on
- cmp flags.comflg,2 ; Check if S-100 ports
- push ax ; Save regs
- push bx
- push cx
- push dx
- jle outch16 ; No, make it simple
- push es
- mov cx,1 ; No delay for sprtch
- call sprtch ; Get possible char at port com3/4
- pop es
- outch16:mov ah,gettim ; Get time function
- int dos
- cmp dl,timer0 ; Normally 0
- pop dx
- pop cx
- pop bx
- pop ax
- jnz outch14 ; No, go loop
- xor timer0,50 ; Yes, move target 1/2 second
- cmp timer0,0 ; This is only true every second
- jnz outch14 ; No, continue looping
- dec timer ; Yes, one second has passed (unless 1st time)
- jnz outch14 ; No, have more seconds left, try again
- mov xofrcv,off ; Timed out, force it off and fall thru.
- OUTCH2 LABEL NEAR ; outch2 entry point without flow control
- mov al,ah ; Routine works on AL.
- call dopar ; Set parity appropriately.
- cmp repflg,0 ; Doing REPLAY from a file?
- je outch24 ; e = no
- and al,7fh ; Strip parity
- cmp al,'C'-40h ; Control-C? (to exit playback mode)
- je outch22 ; e = yes, return failure
- clc ; Return success, send nothing
- ret
- outch22:stc ; Return failure to exit playback mode
- ret
- ;
- outch24:push bx
- push dx
- cmp flags.comflg,2 ; Ports J1/J2
- jle outch4 ; Yes, go handle J1/J2
- mov bl,al ; No, do S-100, save byte to send
- push cx
- xor cx,cx ; Set loop counter
- outch26:push bx ; Check on input
- push cx
- push es
- mov cx,1 ; No delay
- call sprtch ; Get char from port if any
- pop es
- pop cx
- pop bx
- mov dx,mdstat0
- in al,dx ; Check this port
- and al,modsndb ; for ready
- jnz outch28 ; Ready, continue
- loop outch26 ; Not ready, loop until ready or timeout
- jmp short outch44 ; Timed out, return with carry set
- outch28:pop cx
- mov al,bl ; Get back byte to send
- mov dx,mddat0
- out dx,al ; Send it out
- jmp outch8 ; All done S-100 modem
- ;
- outch4: push cx
- xor cx,cx ; Set loop counter
- outch40:mov bx,bufobeg ; get pointer to beginning of que
- sub bx,bufoend ; where are we?
- jnl outch42 ; we did not wrap
- add bx,BUFOLEN ; we have wrapped
- outch42:cmp bx,BUFOLEN-2 ; we have bx char in buffer; is it full?
- jnae outch53 ; no, go on
- loop outch40 ; yes, loop until there is space or timeout
- outch44:pop cx ; timed out
- pop dx
- pop bx
- stc
- ret
- ;
- outch5: push bx ; OUTCH5 entry for SERISR and CHKXON
- push dx ; ah will contain xon or xoff only
- push cx
- xor cx,cx ; Set loop counter
- outch50:mov bx,bufobeg ; get pointer to beginning of que
- sub bx,bufoend ; where are we?
- jnl outch51 ; we did not wrap
- add bx,BUFOLEN ; we have wrapped
- outch51:cmp bx,BUFOLEN ; we have bx char in buffer; is it full?
- jne outch52 ; no, go on
- loop outch50 ; yes, loop until there is space or timeout
- jmp short outch44 ; timed out, no space
- outch52:mov al,ah ; Routine works on AL.
- call dopar ; Set parity appropriately.
- pop cx
- jmp short outch54
- ;
- outch53:pop cx ; restore stack
- cmp bx,0 ; buffer empty?
- jz outch58 ; yes, skip
- cmp flowoff,0 ; Are we doing flow control
- je outch58 ; No, skip
- cmp al,flowoff ; Is it xoff?
- je outch54 ; Yes, this is priority, expedite
- cmp al,flowon ; Is it xon?
- jne outch58 ; No, skip
- ;
- outch54:cli
- mov bx,bufobeg ; beginning of que
- dec bx ; we want space in between, bx still >= 0
- jae outch56 ; yes, go on
- mov bx,BUFOLEN ; wrap
- outch56:mov bufobeg,bx ; new beginning
- mov byte ptr buffout[bx],al ; put char in it
- sti
- jmp short outch6
-
- outch58:mov bx,bufoend
- mov byte ptr buffout[bx],al ; put char in it
- inc bx ; point to next spot in que
- cmp bx,BUFOLEN ; looking at end of que ?
- jne outch6 ; no, OK
- xor bx,bx ; yes, reset pointer
- outch6: mov bufoend,bx ; store new value
- mov dx,portadr
- add dx,PCOMM
- cli
- in al,dx
- test al,TXON ; TX already on ?
- jnz outch7 ; yes, OK
- or al,TXON ; no, turn it on
- out dx,al ; it's on
- outch7: sti ; done with 2661
- outch8: pop dx
- pop bx
- clc ; success, return with carry cleared
- ret
- OUTCHR ENDP
-
- ; Move the cursor to the left margin, then clear to end of line.
- CTLU PROC NEAR
- mov ah,prstr
- mov dx,offset clrlin
- int dos
-
- ; Clear to the end of the current line
- CLEARL PROC NEAR
- push ax
- push dx
- mov ah,prstr
- mov dx,offset eeolstr ; Erase to end of line
- int dos
- pop dx
- pop ax
- ret
- CLEARL ENDP
- CTLU ENDP
-
- ; This routine blanks the screen and homes the cursor. Uses ax and dx.
- CMBLNK PROC NEAR
- mov ah,prstr
- mov dx,offset clrstr ; Home cursor, blank screen
- int dos
- ret
- CMBLNK ENDP
-
- ; Locate: homes the cursor. Uses ax and dx.
- LOCATE PROC NEAR
- mov ah,prstr
- mov dx,offset home ; Go to top left corner of screen.
- int dos
- LOCATE ENDP
-
- ; write a line in inverse video at the bottom of the screen...
- ; the line is passed in dx, terminated by a $.
- PUTMOD PROC NEAR
- push ax ; save regs
- push dx ; preserve message
- mov ah,prstr
- mov dx,offset savcur
- int dos
- mov dx,offset enamod
- int dos
- mov dx,offset lin25
- int dos
- mov dx,offset begrev
- int dos
- pop dx ; get message back
- int dos ; write it out
- mov dx,offset endrev
- int dos
- mov dx,offset precur
- int dos
- pop ax
- ret ; and return
- PUTMOD ENDP
-
- ; clear the mode line written by putmod.
- CLRMOD PROC NEAR
- mov ah,prstr
- mov dx,offset dismod
- int dos
- ret
- CLRMOD ENDP
-
- BEEP PROC NEAR
- push ax ; save regs
- push dx ; preserve message
- mov ah,conout
- mov dl,BELL ; ASCII BEL
- int dos ; Ring it
- pop dx
- pop ax
- clc
- ret
- BEEP ENDP
-
- ; Put a help message on the screen. This one uses reverse video...
- ; pass the message in ax, terminated by a null. Messes up ax, bx, cx, dx.
- PUTHLP PROC NEAR
- push si
- push ax ; preserve this
- mov dx,offset crlf
- int dos
- pop si ; point to string again
- jmp short puthl3 ; assume message begins with cr and lf
- puthl2: call getpos ; get cursor pos into dx
- mov ax,dx ; from row ah, col al
- mov bx,dx
- mov bl,COLUMNS ; to row bh, col bl
- mov dx,word ptr doscol ; dos color reversed
- call setcol ; set this color
- call atsclr ; and clear the line
- puthl3: mov cx,COLUMNS - 1 ; characters on a line less one (starts at 0)
- puthl4: lodsb ; get a byte
- mov ah,conout ; print char
- cmp al,0 ; end of string?
- je puthl5 ; yes, stop
- cmp al,lf ; lf ?
- je puthl7 ; end of line, do new one
- cmp cx,0 ; last column
- je puthl6 ; no more space on line, get new one
- mov dl,al ; else, print char
- int dos
- jmp short puthl3 ; get next char
- puthl5: pop si
- ret
- puthl6: mov dl,cr
- int dos
- puthl7: mov dl,lf
- int dos
- jmp short puthl2
-
- PUTHLP ENDP
-
- ; Set the baud rate for the current port, based on the value
- ; in the portinfo structure. Returns carry clear.
- BAUDST PROC NEAR
- mov dx,offset bdtab ; baud rate table, ascii
- xor bx,bx ; help is the table itself
- mov ah,cmkey ; get keyword
- call comnd
- jc baudst1 ; c = failure
- push bx ; save result
- mov ah,cmeol ; get confirmation
- call comnd
- pop bx
- jc baudst1 ; c = failure
- push si
- mov si,portval
- mov ax,[si].baud ; remember original value
- mov [si].baud,bx ; set the baud rate
- pop si
- call dobaud ; use common code
- clc
- baudst1:ret
- BAUDST ENDP
-
- DOBAUD PROC NEAR
- push ax ; save some regs
- push bx
- push cx
- push dx
- mov bp,portval ; Pointer to port data structure
- mov temp,ax ; Don't overwrite previous rate
- mov ax,ds:[bp].baud ; Check if new rate is valid
- shl ax,1 ; Get index into baud table
- mov bx,offset bddat ; Start of table.
- add bx,ax
- mov ax,[bx] ; The data to output to port.
- cmp ax,0FFH ; Unimplemented baud rate.
- jne dobd0
- mov ax,temp ; Get back orginal value.
- mov ds:[bp].baud,ax ; Leave baud rate as is.
- mov ah,prstr
- mov dx,offset badbd ; Give an error message.
- int dos
- stc ; Failure
- jmp dobd2
- dobd0: mov ds:[bp].baud,ax ; Put in new baud rate
- cmp flags.comflg,2 ; is it J1/J2?
- jle dobd1 ; yes, go do J1/J2 stuff
- call serini ; go set rate in S-100 modem
-
- jmp dobd2
- dobd1: mov dx,portadr ; get addr to send it
- add dx,PMODE
- push ax ; save baud
- mov al,MODE1
- cli ; none while setting 2661
- out dx,al ; mode reg 1/2
- pop ax ; get baud back
- and al,0fH ; make sure it's clean
- or al,MODE2 ; make complete mode 2/2 command
- out dx,al ; set mode reg 2/2
- sti ; done with 2661
- clc ; Success
- dobd2: pop dx ; restore regs
- pop cx
- pop bx
- pop ax
- ret
- DOBAUD ENDP
-
- ; Get the current baud rate from the serial card and set it
- ; in the portinfo structure for the current port.
- ; Also finds out which serial port, A (COM2) or B (COM1), is defined
- ; as default by Zenith Configur.
- ; This is used during initialization.
- GETBAUD PROC NEAR
- cmp flags.comflg,2 ; J1/J2?
- jg getbau3 ; No, all done
-
- push ax
- push bx
- push dx
- push di
- cmp portadr,0 ; Just started Kermit?
- jnz getbau2 ; No, skip this
- mov bx,ds ; Set up pointer to config info
- mov es,bx
- mov bx,offset auxconf
- mov ah,chr_status
- mov al,chr_sfgc ; Get current config info
- call bios_auxfunc
- cmp auxconf.cfport,mdmdat1 ; Is it B?
- jne getbau1 ; ne = no
- mov flags.comflg,1 ; Set flag to indicate port B
- mov portval,offset port1
- mov mddat0,mdmdat1
- mov portadr,mdmdat1
- mov mdstat0,mdmcom1
- jmp getbau2
- getbau1:mov flags.comflg,2 ; Set flag to indicate port A
- mov portval,offset port2
- mov mddat0,mdmdat2
- mov portadr,mdmdat2
- mov mdstat0,mdmcom2
- getbau2:mov dx,portadr ; Get addr to retrieve mode from
- add dx,PMODE
- in al,dx ; Read and discard mode 1/2
- in al,dx ; mode 2/2 has baud rate
- and ax,000fH ; Clean it up
- mov bp,portval
- mov ds:[bp].baud,ax ; Put it in portinfo struct
- pop di
- pop dx
- pop bx
- pop ax
- getbau3:ret
- GETBAUD ENDP
-
- ; Get Char from serial port buffer.
- ; returns carry set if no character available at port, otherwise prtchr
- ; returns carry clear with char in al, # of chars in buffer in dx and count.
- PRTCHR PROC NEAR
- cmp flags.comflg,2 ; check if S-100 ports
- jg prtch4 ; Yes, go do S-100 stuff
- call chkxon ; see if we need to xon
- cmp repflg,0 ; REPLAY?
- je prtch0 ; e = no
- jmp prtch30 ; yes, do replay file reading
- prtch0: cli ; dont let intterrupts touch buffers
- mov dx,bufiend ; compute number of chars in
- sub dx,bufibeg ; input que
- jge prtch1 ; is it wrapped around
- add dx,BUFILEN ; yes, make it +
- prtch1: cmp dx,0 ; anything in there ?
- jne prtch2 ; ne = yes. [jrd]
- mov count,dx
- sti
- stc ; no
- ret
- prtch2: mov bx,bufibeg ; yes, get the char, get the position
- mov al,byte ptr buffin[bx] ; get the char
- inc bx ; bump the position ptr
- cmp bx,BUFILEN ; wrap it ?
- jne prtch3
- xor bx,bx ; yes, reset pointer
- prtch3: mov bufibeg,bx ; store new value
- dec dx ; we took one char out
- mov count,dx ; save
- sti
- clc ; yes, got it
- ret
- prtch4:
- push ax ; First check port for possible input
- push bx
- push cx
- push es
- mov cx,1 ; Parameter for sprtch, cx=1 means don't loop
- call sprtch ; Read port
- pop es
- pop cx
- pop bx
- pop ax
- cmp repflg,0 ; REPLAY?
- je prtch41 ; e = no
- jmp prtch30 ; yes, do replay file reading
- prtch41:cmp count,0 ; Buffer empty?
- jne prtch5 ; ne = no, get char
- mov dx,0 ; Nothing there Is this needed?
- stc ; Got nothing
- ret
- prtch5: push si ; Don't mess up, used by spack
- mov si,srcpnt ; Point to next character in que
- cld
- lodsb ; Get the next one
- cmp si,offset source + bufsiz ; Bigger than buffer?
- jb prtch6 ; No, keep going
- mov si,offset source ; Yes, wrap around
- prtch6: dec count
- mov dx,count
- mov srcpnt,si
- pop si ; Left in good shape
- clc ; Yes, got it
- ret
- prtch30:cmp repflg,2 ; at EOF already?
- jne prtch31 ; ne = no
- stc ; yes, return with no char
- ret
- prtch31:push bx ; REPLAY, read char from a file
- push cx
- xor dx,dx
- test xofsnt,usron ; user level xoff sent?
- jz prtch32 ; z = no
- pop cx ; suppress reading here
- pop bx
- stc ; return with no char
- ret
- prtch32:mov ax,100
- mov bx,1
- jmp $+2 ; flush lookahead buffer
- div bx ; burn some cpu cycles
- div bx ; because a 1 ms wait is too long
- div bx
- div bx
- mov ah,readf2
- mov bx,diskio.handle ; file handle
- mov cx,1 ; read one char
- mov dx,offset rdbuf ; to this buffer
- int dos
- jc prtch34 ; c = read failure
- cmp ax,cx ; read the byte?
- jne prtch34 ; ne = no
- pop cx
- pop bx
- mov al,rdbuf ; get the char into al
- mov dx,1 ; external char count
- clc
- ret ; return it
- prtch34:call beep
- mov ax,40 ; wait 40 millisec
- call pcwait
- call beep
- mov repflg,2 ; say at EOF
- pop cx
- pop bx
- stc ; say no char
- ret
- PRTCHR ENDP
-
- ; Examine incoming communications stream for a packet SOP character.
- ; Return CX= count of bytes starting at the SOP character (includes SOP)
- ; and carry clear. Return CX = 0 and carry set if SOP is not present.
- ; Destroys AL.
- peekcom proc far
- mov cx,count ; qty in circular buffer
- cmp cx,6 ; basic NAK
- jb peekc4 ; b = two few chars, get more
- push bx
- cli ; interrupts off, to keep srcpnt & count consistent
- mov bx,srcpnt ; address of next available slot in buffer
- sub bx,cx ; minus number of unread chars in buffer
- cmp bx,offset source ; located before start of buf?
- jae peekc1 ; ae = no
- add bx,bufsiz ; else do arithmetic modulo bufsiz
- peekc1: mov al,[bx]
- cmp al,trans.rsoh ; packet receive SOP?
- je peekc3 ; e = yes
- inc bx
- cmp bx,offset source+bufsiz ; beyond end of buffer?
- jb peekc2 ; b = no
- mov bx,offset source ; wrap around
- peekc2: loop peekc1 ; keep looking
- sti
- pop bx
- stc ; set carry for no SOP
- ret
- peekc3: sti ; interrupts back on now
- pop bx
- inc cx ; include SOP in count
- clc ; say SOP found
- ret ; CX has count remaining
-
- peekc4: xor cx,cx ; return count of zero
- stc ; say no data
- ret
- peekcom endp
-
-
- ; local routine to see if we have to transmit an xon when com1/2
- chkxon proc near
- cmp xofsnt,false ; have we sent an xoff?
- je chkxo1 ; no, forget it
- cmp flowoff,0 ; Are wo doing flow control?
- je chkxo1 ; no, skip all this
- test xofsnt,usron ; did user send an xoff?
- jnz chkxo1 ; nz = yes, don't contradict it here
- test xofsnt,bufon ; have we sent a buffer level xoff?
- jz chkxo1 ; z = no, forget it
- cmp count,mntrgl ; below trigger?
- jae chkxo1 ; no, forget it
- mov ah,flowon ; xon
- call outch5 ; send it
- jc chkxo1 ; failure
- and xofsnt,false ; remember we've sent the xon.
- chkxo1: ret ; and return
- chkxon endp
-
- ; Local routine to see if we have to transmit an xoff or xon when com3/4
- ; this is probably overdoing it
- ; called by sprtch
- chkxof proc near
- cmp flowoff,0 ; Are wo doing flow control?
- je chkxof1 ; no, skip all this
- test xofsnt,usron ; did user send an xoff?
- jnz chkxof1 ; nz = yes, don't contradict it here
- test xofsnt,bufon ; have we sent a buffer level xoff?
- jz chkxof1 ; z = no, forget it
- cmp count,mntrgh ; Buffer filling up?
- jb chkxof3 ; no, go check that xon sent
- cmp xofsnt,true ; yes, have we sent an xoff?
- je chkxof1 ; yes, all done
- mov ah,flowoff ; xoff
- mov xofsnt,true ; remember we've sent the xoff.
- jmp short chkxof2 ; go send xoff
- chkxof3:cmp count,mntrgl ; below trigger
- jae chkxof1 ; no, forget it
- cmp xofsnt,false ; xon sent?
- je chkxof1 ; all done
- mov ah,flowon ; xon
- chkxof2:call outch2 ; send it
- chkxof1:ret ; and return
- chkxof endp
-
- ; Read the serial port for the S-100 modem and put input in buffer.
- ; Call with delay loop count in cx, c = 1 means no delay.
- ; Input stream is monitored for xon/xoff.
- ; Called by outchr, prtchr and outtty.
- ; Destroys ax, bx, cx, dx, es
- SPRTCH PROC NEAR
- mov bx,ds ; Point to data segment
- mov es,bx
- mov dx,mdstat0 ; Check
- in al,dx ; status
- and al,modrcvb ; Character at port?
- jnz sprtch2 ; Yes, go get it
- call chkxof
- loop sprtch0 ; Keep checking port if cx not=1
- ret ; No data
-
- sprtch0:push cx
- xor cx,cx ; This is a delay loop to expand the delay for
- mov cl,trans.rtime ; screen escape sequencies and capture.
- or cx,cx ; avoid 0, it will loop for ever
- jnz sprtch1
- inc cx
- sprtch1:loop sprtch1 ; The delay time is controlled through the
- pop cx ; receive timeout setting.
- jmp sprtch
-
- sprtch2:mov dx,mddat0 ; Get
- in al,dx ; character
- mov ah,al ; Make working copy
- and ah,parmsk ; Strip parity
- mov bx,portval
- cmp [bx].floflg,0 ; Are we doing flow control.
- jz sprtch4 ; No, skip
- mov dx,[bx].flowc
- cmp ah,dh ; xon?
- jne sprtch3 ; No, check xoff
- mov xofrcv,off ; Set flag to indicate xoff not received (xon)
- jmp short sprtch6 ; Get the next char
-
- sprtch3:cmp ah,dl ; xoff?
- jne sprtch4 ; No, go do normal buffer handling
- mov xofrcv,true ; Set flag to indicatae xoff received
- jmp short sprtch6 ; Get the next char
-
- sprtch4:push di
- mov di,savedi ; Point to last received char
- cld
- stosb ; Save the next one
- cmp di,offset source + bufsiz ; Bigger than buffer?
- jb sprtch5 ; No, keep going
- mov di,offset source ; Yes, wrap around
- sprtch5:inc count
- mov savedi,di
- pop di
- sprtch6:call chkxof
- loop sprtch0 ; Keep checking port if cx not=0
- ret
- SPRTCH ENDP
-
- ; IHOSTS - Initialize the host by sending XOFF, or equivalent.
- ; Requires that the port be initialized before hand.
- ; Do not send flow control if doing half duplex.
- IHOSTS PROC NEAR
- push ax ; save the registers
- push cx
- push dx
- mov xofrcv,off ; clear old xoff received flag
- mov xofsnt,off ; and old xoff sent flag
- mov ah,flowoff ; put wait flow control char in ah
- or ah,ah ; check for null char
- jz ihosts1 ; z = null, don't send it
- cmp dupflg,0 ; full duplex?
- jne ihosts1 ; ne = no, half
- call outchr ; send it
- ihosts1:call clrbuf ; clear out interrupt buffer
- pop dx ; empty buffer. we are done here
- pop cx
- pop ax
- ret
- IHOSTS ENDP
-
- ; IHOSTR - initialize the remote host for our reception of a file by
- ; sending the flow-on character (XON typically) to release any held
- ; data. Called by receive-file code just after initializing the serial
- ; port. 22 March 1986 [jrd]
- IHOSTR PROC NEAR
- push ax ; save regs
- push bx
- push cx
- mov bx,portval ; port indicator
- mov ax,[bx].flowc ; put Go-ahead flow control char in ah
- or ah,ah ; check for null char
- jz ihostr1 ; z = null, don't send it
- call outchr ; send it (release Host's output queue)
- ihostr1:pop cx
- pop bx
- pop ax
- ret
- IHOSTR ENDP
-
-
- ; Global proc to Hangup the Phone or Network by making DTR and
- ; RTS low (phone).
- DTRLOW PROC NEAR
- mov ah,cmline ; allow text, to be able to display help
- mov bx,offset rdbuf ; dummy buffer
- mov dx,offset hnghlp ; help message
- call comnd ; get a confirm
- jc dtrlow3 ; c = failure
- cmp flags.comflg,'0' ; Bios?
- jb dtrlow1 ; b = no, UART
- cmp flags.comflg,'4' ; Bios?
- jbe dtrlow2 ; be = yes, can't access modem lines
- dtrlow1:call serhng ; drop DTR and RTS
- cmp taklev,0 ; in a Take file or macro?
- jne dtrlow2 ; ne = yes, no message
- mov ah,prstr ; give a nice message
- mov dx,offset hngmsg
- int dos
- dtrlow2:clc ; success
- dtrlow3:ret
- DTRLOW ENDP
-
- ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
- ; to terminate the connection. (com1 and com2)
- ; The USR S-100 modem will not respond to dropping of DTR. Instead the +++
- ; sequence must be sent.
- ; Calling this twice without intervening calls to serini should be harmless.
- SERHNG PROC NEAR
- cmp flags.comflg,2 ; Which port?
- jg serhng1
- cli
- call porton ; Insure that DTR and RTS are high
- sti
- mov dx,portadr
- add dx,PCOMM
- in al,dx
- xor al,DTR ; Drop DTR
- xor al,RTS ; Drop RTS
- out dx,al
- mov ax,500 ; 500 millisec, for pcwait
- call pcwait ; keep lines low for at least 500 millisec
- clc
- ret
- serhng1:mov dx,mdstat0 ; Port address. [19b]
- in al,dx ; Get status
- and al,moddcdb ; Carrier?
- jz serhng4 ; No, tell user
- mov ah,prstr ; Yes, tell user to wait
- mov dx,offset wmsg
- int dos
- mov ax,1100 ; 1100 milliseconds
- call pcwait ; Wait before sending '+++'
- push si
- mov si,offset hngstr ; Point to '+++'
- cld
- lodsb ; Get the first byte of string
- serhng2:push ax ; We need the loaded byte later
- mov dx,mdstat0 ; The status port
- serhng3:in al,dx ; Get status
- and al,modsndb ; Mask for ready
- jz serhng3 ; No, go on
- pop ax ; Get byte back
- mov dx,mddat0 ; The data port
- out dx,al ; Send it out
- lodsb ; Load next byte
- cmp al,'$' ; Finished?
- jnz serhng2 ; No, process next
- pop si
- mov ax,1100 ; 1100 milliseconds
- call pcwait ; Wait after sending '+++'
- mov dx,mdstat0 ; Port address. [19b]
- in al,dx ; Get status
- and al,moddcdb ; Carrier?
- serhng4:mov ah,prstr
- mov dx,offset dscmsg ; Point to message
- clc
- jz serhng5 ; Yes, no carrier, go tell user
- inc cl ; No, carrier detected
- cmp cl,3 ; Try three times
- jnz serhng1 ; No, go try again
- mov dx,offset ndscmsg ; Warn user
- serhng5:int dos ; all done
- ret
- SERHNG ENDP
-
- ; Send a break out the current serial port.
- SENDBR PROC NEAR
- mov brkdur,28 ; Normal break 280ms
- jmp sendbr1
- sendbl: mov brkdur,180 ; Long break 1800ms
- jmp sendbr1
- sendbr1:push cx
- push dx
- push ax
- mov dx,mdstat0 ; Port address
- cmp flags.comflg,2 ; Which port?
- jg sendbr3
- in al,dx ; Get current setting
- or al,brkval ; Set send-break bit(s)
- out dx,al ; Start the break
- mov bx,brkdur ; wait this long
- call wait01 ; hold break for desired interval
- xor al,brkval ; Clear send-break bit(s)
- out dx,al ; Stop the break
- sendbr2:pop ax
- pop dx
- pop cx
- ret
- sendbr3:call pickspd ; Point to speed
- mov al,[bx+1] ; Command byte
- sub al,8h ; Break byte 8h lower (1fh and 3fh)
- cmp al,1fh
- je sendbr4
- mov al,3fh
- sendbr4:out dx,al
- mov bx,brkdur ; wait this long
- call wait01
- call initmod
- jmp sendbr2
- SENDBR ENDP
-
- ; Position the cursor according to contents of DX:
- ; DH contains row, DL contains column.
- POSCUR PROC NEAR
- push ax
- push dx
- cmp flags.comflg,2 ; Ports 1/2
- jna poscur1 ; Yes, skip this
- push bx ; No, check input port
- push cx
- push es
- mov cx,1 ; No delay
- call sprtch ; Get char from port if any
- pop es
- pop cx
- pop bx
- poscur1:mov ah,conout
- mov dl,ESCAPE
- int dos
- mov dl,'Y'
- int dos
- pop dx
- push dx
- mov dl,dh
- add dl,' '
- int dos
- pop dx
- add dl,' '
- int dos
- pop ax
- ret
- POSCUR ENDP
-
-
- ; Delete a character from the terminal. This works by printing
- ; backspaces and spaces.
- DODEL PROC NEAR
- mov ah,prstr
- mov dx,offset delstr ; Erase weird character.
- int dos
- ret
- DODEL ENDP
-
- ; select port to be current. Returns with carry clear if success.
- COMS PROC NEAR
- ; mov kstatus,0 ; global status, success
- mov dx,offset comptab ; table of legal comms ports
- mov bx,offset comsmsg ; point to comsmsg
- mov ah,cmkey ; parse key word
- call comnd
- jnc coms0 ; nc = success
- ret ; failure
- coms0: call serrst ; uninstall interrupt
- call comstrt
- jnc coms1
- mov ah,prstr
- mov dx,offset coms0msg ; Point to no S-100 modem msg
- int dos
- coms1: clc
- ret
-
- comstrt:mov al,flags.comflg
- mov tmp,al ; Save the old one in case
- mov flags.comflg,bl ; Set the comm port flag.
- cmp bl,1 ; COM1 (port B)?
- je coms2 ; Yes
- cmp bl,2 ; COM2 (port A)?
- je coms3 ; Yes
- cmp bl,3 ; COM3 (S-100 modem port 1)
- je coms4 ; Yes
- in al,mdmcom4 ; Check this port
- and al,modperb ; Is it there?
- jnz coms6 ; No, skip
- mov portval,offset port4 ; Must be COM4
- mov mddat0,mdmdat4
- mov mdstat0,mdmcom4
- jmp coms5
- coms4: in al,mdmcom3 ; Check this port
- and al,modperb ; Is it there?
- jnz coms6 ; No, skip
- mov portval,offset port3
- mov mddat0,mdmdat3
- mov mdstat0,mdmcom3
- jmp coms5
- coms2: mov mdstat0,mdmcom1 ; Set break address for B
- mov portadr,mdmdat1 ; Set address for B
- mov portval,offset port1 ; Point to portinfo for B
- jmp coms5
- coms3: mov mdstat0,mdmcom2 ; Set break address for A
- mov portadr,mdmdat2 ; Set address for A
- mov portval,offset port2 ; Point to portinfo for A
- coms5: call baudref ; Set up bdtab and bddat
- call getbaud ; See what is in the port now set
- clc ; Success
- ret
- coms6: mov al,tmp
- mov flags.comflg,al ; Get the old one back
- stc ; Failure
- ret
- COMS ENDP
-
- ; Set heath emulation on/off.
- ; SET Term parameters, especially for use with VT100 emulator. [jrd]
- ; Taken from work done originally by James Harvey IUPUI.
- ; VTS is called only by mssset to set terminal type and characteristics.
- ; Enter via direct jmp. Exit ret with carry set for failure, else carry
- ; cleared.
- VTS proc near ; SET TERM whatever
- mov dx,offset termtb ; terminal table, ascii
- xor bx,bx ; help is the table itself
- mov ah,cmkey ; get keyword
- call comnd
- jnc vset1 ; nc = success
- ret ; failure
- vset1: mov flags.vtflg,bx ; Set the Heath emulation flag
- and bx,bx ; emulating?
- mov dosflg,0ffh ; set the flag, disable scan codes
- mov flags.xltkbd,0 ; key translation disabled
- jz vset2 ; nz=yes
- mov dosflg,0 ; clear the flag, enable scan codes
- mov flags.xltkbd,1 ; key translation enabled
- vset2: mov dx,offset vtsmsg
- mov ah,prstr
- int dos
- clc ; success
- ret
- VTS ENDP
-
- VTSTAT PROC NEAR ; For Status display [jrd]
- ret ; no emulator status to display
- VTSTAT ENDP
-
-
- ; simple routine to insure that the port has RXON and DTR high
- ; assumes int are off
- porton proc near
- push dx
- push ax
- mov dx,portadr
- add dx,PCOMM
- in al,dx
- or al,RXON
- or al,DTR
- or al,RTS
- out dx,al
- pop ax
- pop dx
- ret
- porton endp
-
- ; routine to retrieve current int vector
- ; inputs: al = int number
- ; outputs: cx = seg for current isr
- ; dx = offset for current isr
- getivec proc near
- push es ; save registers
- push bx
- mov ah,35H ; Int 21H, function 35H = Get Vector.
- int dos ; get vector in es:bx
- mov cx,es ; addr of org vector (seg)
- mov dx,bx ; and offset
- pop bx
- pop es
- ret
- getivec endp
-
- ; routine to set int vector
- ; inputs: al = int number
- ; cx = seg for isr
- ; dx = offset for isr
- setivec proc near
- push ds ; save ds around next DOS call.
- mov ds,cx
- mov ah,25H ; set interrupt address from ds:dx
- int dos
- pop ds
- ret
- setivec endp
-
-
- ; initialization for using serial port. This routine performs
- ; any initialization necessary for using the serial port, including
- ; setting up interrupt routines, setting buffer pointers, etc.
- ; Doing this twice in a row should be harmless (this version checks
- ; a flag and returns if initialization has already been done).
- ; SERRST below should restore any interrupt vectors that this changes.
- SERINI PROC NEAR
- cmp portin,0 ; did we initialize port already?
- je serin1 ; e = yes
- jl serin0 ; l = no, not yet
- jmp serin2
- serin0: mov bl,flags.comflg ; pass current port ident
- call comstrt ; do SET PORT now
- jnc serin1 ; nc = success
- ret ; failed, exit now
- serin1: cmp flags.comflg,2 ; COM1 or COM2?
- jle serini1 ; Go do COM1/COM2 stuff
- serin2: cmp flags.comflg,2 ; COM1 or COM2?
- jg serini2 ; Go do COM3/COM4 stuff
- jmp serini3 ; Update flow and leave
- initmod: ; The S-100 modem set up routine
- serini2:call pickspd ; Select baud and speed info
- xor al,al ; Use this to reset modem
- mov dx,mdstat0 ; Status port
- out dx,al ; Send to port
- jmp $+2 ; Wait a little
- out dx,al
- jmp $+2 ; Wait a little
- out dx,al
- jmp $+2 ; Wait a little
- mov al,40h
- out dx,al
- jmp $+2 ; Wait a little
- mov al,[bx]
- out dx,al
- jmp $+2 ; Wait a little
- mov al,[bx+1]
- out dx,al
- jmp $+2
- in al,dx ; Check port
- and al,moddcdb ; for carrier
- jnz serini0 ; Yes, don't do AT stuff
- mov bx,10 ; Wait 10/100 seconds
- call wait01 ; Call wait routine
- push si
- mov si,offset set_str;ATE1X1S0=0 sets up modem: echo commands, use
- cld ; extended response codes, don't answer
- lodsb ; Get the first byte of string
- serini5:push ax ; We need the loaded byte later
- serini6:xor cx,cx ; Reset loop counter. Loop to avoid hanging
- mov dx,mdstat0 ; The status port
- serini7:in al,dx ; Get status
- and al,modsndb ; Mask for ready
- jnz serini8 ; Yes, go on
- inc cx ; No
- or cx,cx ; Run out?
- jnz serini7 ; No, try again
- mov ah,prstr ; Yes, tell user failure in initialization
- mov dx,offset infmsg; Tell user init failed
- int dos
- pop ax ; Restore stack
- pop si
- stc ; Failure
- ret
- serini8:pop ax ; Get byte back
- mov dx,mddat0 ; The data port
- out dx,al ; Send it out
- lodsb ; Load next byte
- cmp al,'$' ; Finished?
- jnz serini5 ; No, process next
- pop si ; Left in good order
- mov bx,25 ; Wait 25/100 seconds
- call wait01 ; Call wait routine
- call prtchr ; Purge modem
- jmp serini3 ; Success
-
- serini1:mov ax,portval
- cmp ax,offset port2
- je seri2 ; setup for J1
- cmp intin,2
- jne seri0
- serini0:clc ; Success
- ret ; J2 (com3, com4) already set up
- seri0: cmp intin,1
- jne seri1 ; J1 currently installed
- call serrst ; de-install current int
- seri1: mov al,J2INT
- call getivec
- mov oldseg,cx
- mov oldoff,dx
- mov cx,cs
- mov dx,offset serisr
- mov al,J2INT
- call setivec
- mov portadr,J2_ADDR
- call clrbuf
- call porton
- mov intin,2 ; show J2 installed
- jmp serini3 ; Success
- seri2: cmp intin,1
- jne seri3
- clc ; Success
- ret ; J1 already set up
- seri3: cmp intin,2
- jne seri4 ; J2 currently installed
- call serrst ; de-install current int
- seri4: mov al,J1INT
- call getivec
- mov oldseg,cx
- mov oldoff,dx
- mov cx,cs
- mov dx,offset serisr
- mov al,J1INT
- call setivec
- mov portadr,J1_ADDR
- call clrbuf
- call porton
- mov intin,1 ; show J1 installed
-
- serini3:push bx
- mov bx,portval ; get port data structure
- mov [bx].portrdy,1 ; say the comms port is ready
- mov parmsk,0ffh ; parity mask, assume parity is None
- cmp [bx].parflg,parnon ; is it None?
- je serini3a ; e = yes
- mov parmsk,07fh ; no, pass lower 7 bits as data
- serini3a:xor ax,ax
- cmp [bx].floflg,0 ; flow control is off?
- je serini3b ; e = yes
- mov ax,[bx].flowc ; get flow control chars
- serini3b:mov flowoff,al ; xoff or null
- mov flowon,ah ; xon or null
- mov xofrcv,off ; clear xoff received flag
- pop bx
- mov portin,1 ; say initialized
- clc ; carry clear for success
- ret ; We're done
-
- pickspd:mov bp,portval ; Get speed for S-100 modem 'from' portval
- cmp ds:[bp].baud,0 ; 150 baud?
- mov bx,offset bd150
- jz serini4
- cmp ds:[bp].baud,1 ; 300 baud?
- mov bx,offset bd300
- jz serini4
- cmp ds:[bp].baud,2 ; 600 baud?
- mov bx,offset bd600
- jz serini4
- mov bx,offset bd1200; Default to 1200 baud
- serini4:ret
- SERINI ENDP
-
- ; Reset the serial port. This is the opposite of serini. Calling
- ; this twice without intervening calls to serini should be harmless.
- SERRST PROC NEAR
- cmp portin,0 ; Reset already?
- jg serr0 ; g = no
- clc
- ret ; e = yes, l=not used yet, just leave
- serr0: push dx
- cmp intin,0 ; is any isr installed
- je serr2 ; no, all done
- push cx
- push ax
- mov ax,J2INT ; guess it's J2
- cmp intin,2 ; yes,
- je serr1 ; reset it
- mov ax,J1INT ; no, must be J1
- serr1: mov cx,oldseg ; original isr
- mov dx,oldoff ; address
- call setivec ; do it
- mov intin,0 ; show nothing installed
- call porton ; Insure that DTR and RTS are high
- pop ax
- pop cx
- serr2: pop dx
- mov portin,0 ; reset flag
- push bx
- mov bx,portval ; port data structure
- mov [bx].portrdy,0 ; say port is not ready
- pop bx
- clc
- ret
- SERRST ENDP
-
- ; the serial port interrupt service routine
- ; this routine does int driven input and output
- ; once installed, it displaces the Z-100 serial isr
- serisr: push ax ; Save regs
- push bx
- push cx
- push dx
- push ds ; Save data seg
- mov ax,seg data ; Set our
- mov ds,ax ; data seg
- ;
- mov dx,portadr ; Get the port address
- mov cx,dx ; and save a copy
- add dx,PSTATUS
- in al,dx ; Get port status
- mov ah,al ; Save it
- test ah,RDA ; Check for data available
- jz isr5 ; No, nothing to receive, go send
- ;
- mov dx,cx ; Port address
- in al,dx ; Get the data
- cmp flowoff,0 ; Are wo doing flow control?
- jz isr2 ; No, skip
- ;
- mov ch,al ; Make working copy of data
- and ch,parmsk ; Strip parity, if any
- cmp ch,flowon ; xon?
- jne isr1 ; No, check xoff
- mov xofrcv,false ; Indicate xoff not received (xon)
- ; Done with receiver
- jmp short isr5 ; there should be time for send
- isr1: cmp ch,flowoff ; xoff?
- mov ch,0 ; We need this later in cx
- jnz isr2 ; No, put regular char in buffer
- cmp xofsnt,true ; Did we send an outstanding xoff?
- jz isr5 ; Yes, ignore (possible echo), go send
- mov xofrcv,true ; Set flag to indicatae xoff received
- ; Done with receiver
- jmp short isr5 ; there should still be time for send
- isr2: mov bx,bufiend ; Get where to put it
- cmp count,BUFILEN ; Buffer full?
- jne isr3 ; No, jump
- dec bx ; Don't overwrite que
- mov byte ptr buffin[bx],bell; Put Ctrl-G in the que as marker
- jmp short isr5 ; We missed it anyway
- isr3: mov byte ptr buffin[bx],al ; Stick it in the que
- inc bx ; Bump que pointer
- inc count ; One more in que
- cmp bx,BUFILEN ; Pointing to end of que?
- jne isr4 ; No, go on
- xor bx,bx ; Reset pointer
- isr4: mov bufiend,bx ; Store new pointer
- ; jmp short isr12 ; Pick ; We won't take time to send now
- jmp short isr5 ; one ; There should still be time for send
- ;
- isr5: test ah,TSRE+THBE ; Ready to send?
- jz isr12 ; No, almost done
- mov bx,bufobeg ; Pointer to beginning of output buffer
- cmp count,mntrgh ; Past the high trigger point?
- jnae isr6 ; no, make it simple
- cmp flowoff,0 ; Are we doing flow control?
- jz isr6 ; no, make it simple
- cmp xofsnt,true ; Did we send an xoff already?
- jz isr6 ; yes, make it simple
- mov al,flowoff ; xoff
- or al,al ; Null?
- jz isr6 ; Don't send null
- call dopar
- mov dx,cx ; Port address
- out dx,al ; Send the xoff out
- mov xofsnt,true ; Remember
- cmp bx,bufoend ; Buffer empty?
- jz isr11 ; Yes, turn transmitter off
- jmp short isr12 ; We have used transmitter already,
- ; so we need to go
- isr6: cmp bx,bufoend ; Buffer empty?
- jz isr11 ; Yes, turn transmitter off
- mov al,byte ptr buffout[bx] ; Get char to send
- cmp flowoff,0 ; Are we doing flow control?
- jz isr7 ; No, just go on
- mov ah,al ; Working copy
- and ah,parmsk ; Strip parity
- cmp ah,flowoff ; xoff?
- jz isr7 ; Just send it
- cmp ah,flowon ; xon?
- jz isr7 ; Just send it
- cmp xofrcv,true ; Being held?
- jz isr12 ; Yes, don't send
- isr7: mov dx,cx ; Port address
- out dx,al ; Send it
- inc bx ; Point to next char to send
- cmp bx,BUFOLEN ; Pointing to end of que?
- jne isr10
- xor bx,bx ; Reset pointer
- isr10: mov bufobeg,bx ; Save it
- jmp short isr12 ; Almost done
- ;
- isr11: mov dx,cx ; Port address
- add dx,PCOMM
- in al,dx ; Get current mode
- and al,TXOFF ; Turn xmitter off
- out dx,al ; Do it.
- ;
- isr12: mov al,EOI ; Tell interrupt controller
- out Z8259,al ; that interrupt serviced
- ;
- pop ds ; Restore regs
- pop dx
- pop cx
- pop bx
- pop ax
- iret
-
- ;; Wait for the # of milliseconds in ax, for non-IBM compatibles.
- pcwait proc near
- cmp ax,0
- jz pcwait2 ; no wait
- push bx
- push cx
- push dx
- xor dx,dx
- mov cx,10 ; we can not make it finer than 10ms
- div cx
- cmp ax,0
- jnz pcwait1
- inc ax ; make it 10ms for 1 to 9
- pcwait1:mov bx,ax ; and 10ms for 10 to 19, 20ms for 20 to 29
- call wait01 ; 10ms => 10 to 20ms by wait01
- pop dx ; 20ms => 20 to 30ms by wait01
- pop cx
- pop bx
- pcwait2:ret
- pcwait endp
-
- ; Wait for the # of hundredths seconds in bx. Range 1 to 0ffffh.
- ; Accuracy within 10ms due to use of system clock.
- ; This uses dos calls and is compatible with all msdos systems.
- ; Preserves all registers.
- wait01 proc near
- push ax
- push cx
- push dx
- push di
- mov ah,gettim ; Get time function
- int dos
- wait011:mov di,dx ; Preset/reset di
- wait012:int dos
- cmp dx,di ; Changed?
- je wait012 ; Yes, continue
- dec bx ; 1/100 second passed
- jnz wait011 ; Did not time out, keep waiting
- pop di ; Timed out
- pop dx
- pop cx
- pop ax
- ret
- wait01 endp
-
- ; Service SET NETBIOS-NAME name command at Kermit prompt level
- setnbios proc near
- ret
- setnbios endp
- sesdisp proc near
- ret
- sesdisp endp
- code ends
- end
-